package pws::ex2;

use strict;
use warnings;
use SSWebServer;
use JSON;

# test data. should be in Database.
my %USERS = (
	'demo' => {
		uname => 'demo',
		display_name => 'Richard',
		addr => 'Beijing, China',
		pwd => '1234',
		last_login => now(),
	},
	'demo2' => {
		uname => 'demo2',
		display_name => 'Jason',
		addr => 'Shanghai, China',
		pwd => '1234',
		last_login => now(),
	}
);

# error code definition
my $E_OK = 0;
my $E_PARAM = 1;
my $E_NOAUTH = 2;
my $E_AUTHFAIL = 3;

# for page
my $USER;
sub __begin__
{
	if ($ENV->{METHOD} ne 'login') {
		unless (defined $SES->{user})
		{
			equit($E_NOAUTH, "please login");
		}
		$USER = $SES->{user};
	}
}

# sub __end__
# {
# 	print "END\n";
# }

sub equit # ($errcode, $estr)
{
	setContent(to_json([$_[0], $_[1]]));
	quit();
}

sub setResponse # ($obj)
{
	setContent(to_json([0, $_[0]]));
}

sub now 
{
#  0    1    2     3     4    5     6     7     8
# ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
	my @t = localtime;
	return sprintf "%d/%02d/%02d %02d:%02d:%02d", $t[5]+1900, $t[4]+1, $t[3], $t[2], $t[1], $t[0];
}

# madantory param
sub mparam # ($key, $def_val)
{
	my $v = param($_[0]);
	unless (defined($v)) {
		unless (defined $_[1]) {
			equit($E_PARAM, "require param: $_[0]");
		}
		$v = $_[1];
	}
	$v;
}


sub login : method # (uname, pwd) -> {display_name, last_login}
{
	my $uname = mparam('uname');
	my $pwd = mparam('pwd');
	unless (exists $USERS{$uname}) {
		equit($E_AUTHFAIL, "unknown user");
	}
	$USER = $USERS{$uname};
	if ($USER->{pwd} ne $pwd) {
		equit($E_AUTHFAIL, "wrong password");
	}
	$SES->{user} = $USER;
	setResponse({
		last_login => $USER->{last_login},
	});
	$USER->{last_login} = now();
}

sub logout : method
{
	destroySession();
	setResponse({last_login => $USER->{last_login}});
}

sub getuser : method # () -> {uname, display_name, addr}
{
	setResponse({
			uname => $USER->{uname},
			display_name => $USER->{display_name},
			addr => $USER->{addr},
			last_login => $USER->{last_login},
	});
}

sub changepwd : method # (oldpwd, newpwd)
{
	my $oldpwd = mparam('oldpwd');
	my $newpwd = mparam('newpwd');
	if ($oldpwd ne $USER->{pwd}) {
		equit($E_AUTHFAIL, 'wrong password');
	}
	$USER->{pwd} = $newpwd;
	setResponse('ok');
}

sub setuser : method # (display_name, addr)
{
	my $display_name = param('display_name');
	my $addr = param('addr');
	$USER->{display_name} = $display_name if defined $display_name;
	$USER->{addr} = $addr if defined $addr;
	setResponse('ok');
}

1;
